home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / php / PEAR / CodeGen / Extension.php < prev    next >
Encoding:
PHP Script  |  2007-12-20  |  16.3 KB  |  792 lines

  1. <?php
  2. /**
  3.  * Extension generator class
  4.  *
  5.  * PHP versions 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   Tools and Utilities
  14.  * @package    CodeGen
  15.  * @author     Hartmut Holzgraefe <hartmut@php.net>
  16.  * @copyright  2005 Hartmut Holzgraefe
  17.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18.  * @version    CVS: $Id: Extension.php,v 1.23 2006/07/08 21:28:01 hholzgra Exp $
  19.  * @link       http://pear.php.net/package/CodeGen
  20.  */
  21.  
  22. /**
  23.  * includes
  24.  *
  25.  */
  26. require_once "CodeGen/Maintainer.php";
  27. require_once "CodeGen/License.php";
  28. require_once "CodeGen/Release.php";
  29. require_once "CodeGen/Tools/Platform.php";
  30. require_once "CodeGen/Tools/FileReplacer.php";
  31. require_once "CodeGen/Tools/Outbuf.php";
  32. require_once "CodeGen/Tools/Code.php";
  33. require_once "CodeGen/Dependency/Lib.php";
  34. require_once "CodeGen/Dependency/Header.php";
  35.  
  36. /**
  37.  * Extension generator class
  38.  *
  39.  * @category   Tools and Utilities
  40.  * @package    CodeGen
  41.  * @author     Hartmut Holzgraefe <hartmut@php.net>
  42.  * @copyright  2005 Hartmut Holzgraefe
  43.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  44.  * @version    Release: @package_version@
  45.  * @link       http://pear.php.net/package/CodeGen
  46.  */
  47. abstract class CodeGen_Extension 
  48. {
  49.     /**
  50.     * Current version number
  51.     * 
  52.     * @return string
  53.     */
  54.     abstract public function version();
  55.  
  56.     /**
  57.     * Copyright message
  58.     *
  59.     * @return string
  60.     */
  61.     abstract public function copyright();
  62.  
  63.     /**
  64.      * The extensions basename (C naming rules apply)
  65.      *
  66.      * @var string
  67.      */
  68.     protected $name = "unknown";
  69.     
  70.  
  71.     /**
  72.      * The extensions descriptive name
  73.      *
  74.      * @var string
  75.      */
  76.     protected $summary = "The unknown extension";
  77.     
  78.     /**
  79.      * extension description
  80.      *
  81.      * @var    string
  82.      * @access private
  83.      */
  84.     protected $description;
  85.  
  86.     /** 
  87.      * The license for this extension
  88.      *
  89.      * @var object
  90.      */
  91.     protected $license  = NULL;
  92.     
  93.     /** 
  94.      * The release info for this extension
  95.      *
  96.      * @var object
  97.      */
  98.     protected $release  = NULL;
  99.         
  100.     /** 
  101.      * The implementation language
  102.      *
  103.      * Currently we support "c" and "cpp"
  104.      *
  105.      * @var string
  106.      */
  107.     protected $language  = "c";
  108.     
  109.     /**
  110.      * The target platform for this extension
  111.      *
  112.      * Possible values are "unix", "win" and "all"
  113.      * 
  114.      * @var string
  115.      */
  116.     protected $platform = null;
  117.     
  118.     
  119.     /**
  120.      * The authors contributing to this extension
  121.      *
  122.      * @var array
  123.      */
  124.     protected $authors = array();
  125.     
  126.     
  127.     /**
  128.      * Name prefix for functions etc.
  129.      * 
  130.      * @var string
  131.      */
  132.     protected $prefix = "";
  133.  
  134.  
  135.     /**
  136.      * Release changelog
  137.      *
  138.      * @access private
  139.      * @var     string
  140.      */
  141.     protected $changelog = "";
  142.  
  143.     
  144.     /** 
  145.      * Basedir for all created files
  146.      *
  147.      * @access protected
  148.      * @var    string
  149.      */
  150.     public $dirpath = ".";
  151.  
  152.  
  153.     /**
  154.      * External libraries
  155.      *
  156.      * @var    array
  157.      * @access private
  158.      */
  159.     protected $libs = array();
  160.  
  161.     /**
  162.      * External header files
  163.      *
  164.      * @var    array
  165.      * @access private
  166.      */
  167.     protected $headers = array();
  168.  
  169.     /**
  170.      * Code snippets
  171.      *
  172.      * @var array
  173.      */
  174.     protected $code = array();
  175.  
  176.     /**
  177.      * The package files created by this extension
  178.      *
  179.      * @var array
  180.      */
  181.     protected $packageFiles = array();
  182.  
  183.     /**
  184.      * Version requested by input if any
  185.      *
  186.      * @var string
  187.      */
  188.     protected $version = "";
  189.  
  190.  
  191.     /**
  192.      * Makefile fragments
  193.      *
  194.      * @var    array
  195.      * @access private
  196.      */
  197.     protected $makefragments = array();
  198.  
  199.  
  200.     /**
  201.      * config.m4 fragments
  202.      *
  203.      * @var    array
  204.      * @access private
  205.      */
  206.     protected $configfragments = array("top"=>array(), "bottom"=>array());
  207.  
  208.  
  209.     /**
  210.      * acinclude fragments
  211.      *
  212.      * @var    array
  213.      * @access private
  214.      */
  215.     protected $acfragments = array("top"=>array(), "bottom"=>array());
  216.  
  217.  
  218.     /**
  219.      * CodeGen_Tool_Code instance for internal use
  220.      *
  221.      * @var object
  222.      */
  223.     public $codegen;
  224.  
  225.     // {{{ constructor
  226.  
  227.     /**
  228.      * The constructor
  229.      *
  230.      * @access public
  231.      */
  232.     function __construct() 
  233.     {
  234.         setlocale(LC_ALL, "C"); // ASCII only
  235.  
  236.         if ($this->release == NULL) {
  237.             $this->release = new CodeGen_Release;
  238.         }
  239.         if ($this->platform == NULL) {
  240.             $this->platform = new CodeGen_Tools_Platform("all");
  241.         }
  242.  
  243.         $this->codegen = new CodeGen_Tools_Code;
  244.     }
  245.     
  246.     // }}} 
  247.     /**
  248.      * Set method for changelog
  249.      *
  250.      * @access public
  251.      * @param  string changelog
  252.      * @return bool   true on success
  253.      */
  254.     function setChangelog($changelog)
  255.     {
  256.         $this->changelog = $changelog;
  257.         
  258.         return true;
  259.     }
  260.     
  261.     /**
  262.      * changelog getter
  263.      *
  264.      * @access public
  265.      * @return string
  266.      */
  267.     function getChangelog()
  268.     {
  269.         return $this->changelog;
  270.     }
  271.  
  272.     /**
  273.      * Set extension base name
  274.      *
  275.      * @access public
  276.      * @param  string  name
  277.      */
  278.     function setName($name) 
  279.     {
  280.         if (!preg_match('|^[a-z_]\w*$|i', $name)) {
  281.             return PEAR::raiseError("'$name' is not a valid extension name");
  282.         }
  283.         
  284.         $this->name = $name;
  285.         return true;
  286.     }
  287.  
  288.     /**
  289.      * Get extension base name
  290.      *
  291.      * @return string
  292.      */
  293.     function getName()
  294.     {
  295.         return $this->name;
  296.     }
  297.  
  298.     /**
  299.      * Set extension summary text
  300.      *
  301.      * @access public
  302.      * @param  string  short summary
  303.      */
  304.     function setSummary($text) 
  305.     {
  306.         $this->summary = $text;
  307.         return true;
  308.     }
  309.  
  310.     /** 
  311.      * Set extension documentation text
  312.      *
  313.      * @access public
  314.      * @param  string  long description
  315.      */
  316.     function setDescription($text) 
  317.     {
  318.         $this->description = $text;
  319.         return true;
  320.     }
  321.  
  322.     /**
  323.      * Set the programming language to produce code for
  324.      *
  325.      * @access public
  326.      * @param  string  programming language name
  327.      */
  328.     function setLanguage($lang)
  329.     {
  330.         switch (strtolower($lang)) {
  331.         case "c":
  332.             $this->language = "c";
  333.             $this->codegen->setLanguage("c");
  334.             return true;
  335.         case "cpp":
  336.         case "cxx":
  337.         case "c++":
  338.             $this->language = "cpp";
  339.             $this->codegen->setLanguage("cpp");
  340.             return true;
  341.         default:
  342.             break;
  343.         }
  344.  
  345.         return PEAR::raiseError("'$lang' is not a supported implementation language");
  346.     }
  347.  
  348.     /**
  349.      * Get programming language
  350.      *
  351.      * @return string
  352.      */
  353.     function getLanguage()
  354.     {
  355.         return $this->language;
  356.     }
  357.  
  358.     /**
  359.      * Set target platform for generated code
  360.      *
  361.      * @access public
  362.      * @param  string  platform name
  363.      */
  364.     function setPlatform($type)
  365.     {
  366.         $this->platform = new CodeGen_Tools_Platform($type);
  367.         if (PEAR::isError($this->platform)) {
  368.             return $this->platform;
  369.         }
  370.         
  371.         return true;
  372.     }
  373.  
  374.     /**
  375.      * Add an author or maintainer to the extension
  376.      *
  377.      * @access public
  378.      * @param  object   a maintainer object
  379.      */
  380.     function addAuthor($author)
  381.     {
  382.         if (!is_a($author, "CodeGen_Maintainer")) {
  383.             return PEAR::raiseError("argument is not CodeGen_Maintainer");
  384.         }
  385.         
  386.         $this->authors[$author->getUser()] = $author;
  387.         
  388.         return true;
  389.     }
  390.  
  391.     /** 
  392.      * Set release info
  393.      * 
  394.      * @access public
  395.      * @var    object
  396.      */
  397.     function setRelease($release)
  398.     {
  399.         $this->release = $release;
  400.  
  401.         return true;
  402.     }
  403.  
  404.  
  405.     /** 
  406.      * Set license 
  407.      * 
  408.      * @access public
  409.      * @param  object
  410.      */
  411.     function setLicense($license)
  412.     {
  413.         $this->license = $license;
  414.  
  415.         return true;
  416.     }
  417.  
  418.  
  419.     /**
  420.      * Set extension name prefix (for functions etc.)
  421.      *
  422.      * @access public
  423.      * @param  string  name
  424.      */
  425.     function setPrefix($prefix) 
  426.     {
  427.         if (! CodeGen_Element::isName($prefix)) {
  428.             return PEAR::raiseError("'$name' is not a valid name prefix");
  429.         }
  430.         
  431.         $this->prefix = $prefix;
  432.         return true;
  433.     }
  434.  
  435.     /**
  436.      * Get extension name prefix
  437.      *
  438.      * @return string
  439.      */
  440.     function getPrefix()
  441.     {
  442.         return $this->prefix;
  443.     }
  444.  
  445.     /** 
  446.      * Add verbatim code snippet to extension
  447.      *
  448.      * @access public
  449.      * @param  string  which file to put the code to
  450.      * @param  string  where in the file the code should be put
  451.      * @param  string  the actual code
  452.      */
  453.     function addCode($role, $position, $code)
  454.     {
  455.         if (!in_array($role, array("header", "code"))) {
  456.             return PEAR::raiseError("'$role' is not a valid custom code role");
  457.         }
  458.         if (!in_array($position, array("top", "bottom"))) {
  459.             return PEAR::raiseError("'$position' is not a valid custom code position");
  460.         }
  461.         $this->code[$role][$position][] = $code;
  462.     }
  463.  
  464.  
  465.     /**
  466.      * Add toplevel library dependancy 
  467.      *
  468.      * @var  string  library basename
  469.      */
  470.     function addLib(CodeGen_Dependency_Lib $lib) 
  471.     {
  472.         $name = $lib->getName();
  473.        
  474.         if (isset($this->libs[$name])) {
  475.             return PEAR::raiseError("library '{$name}' added twice");
  476.         }
  477.  
  478.         $this->libs[$name] = $lib;
  479.  
  480.         return true;
  481.     }
  482.  
  483.     /**
  484.      * Add toplevel header file dependancy 
  485.      *
  486.      * @var  string  header filename
  487.      */
  488.     function addHeader(CodeGen_Dependency_Header $header) 
  489.     {
  490.         $name = $header->getName();
  491.        
  492.         if (isset($this->headers[$name])) {
  493.             return PEAR::raiseError("header '{$name}' added twice");
  494.         }
  495.  
  496.         $this->headers[$name] = $header;
  497.  
  498.         // TODO $this->addConfigFragment($header->configm4());
  499.  
  500.         return true;
  501.     }
  502.  
  503.     /**
  504.     * Describe next steps after successfull extension creation
  505.     *
  506.     * @access private
  507.     */
  508.     function successMsg()
  509.     {
  510.         $relpath = str_replace(getcwd(), '.', $this->dirpath);
  511.     
  512.         $msg = "\nYour extension has been created in directory $relpath.\n";
  513.         $msg.= "See $relpath/README and $relpath/INSTALL for further instructions.\n";
  514.  
  515.         return $msg;
  516.     }
  517.  
  518.     /**
  519.      * Get requested version
  520.      *
  521.      * @return  string
  522.      */
  523.     function getVersion()
  524.     {
  525.         return $this->version;
  526.     }
  527.  
  528.     /**
  529.      * Set requested version
  530.      *
  531.      * @param  string
  532.      */
  533.     function setVersion($version)
  534.     {
  535.         if (!preg_match('/^\d+\.\d+\.\d+(dev|alpha|beta|gamma|rc|pl)?\d*$/', $version)) {
  536.             return PEAR::raiseError("'$version' is not a valid version number");
  537.         }
  538.         
  539.         if (version_compare($version, $this->version(), ">")) {
  540.             return PEAR::raiseError("This is ".get_class($this)." ".$this->version().", input file requires at least version $version ");
  541.         }
  542.         
  543.         $this->version = $version;
  544.         return true;
  545.     }
  546.  
  547.     /**
  548.      * Check requested version
  549.      *
  550.      * @param  string version
  551.      * @return bool
  552.      */
  553.     function haveVersion($version)
  554.     {
  555.         return version_compare(empty($this->version) ? $this->version() : $this->version, $version) >= 0;
  556.  
  557.         return true; // 
  558.     }
  559.  
  560.     /**
  561.      * Add a package file by type and path
  562.      *
  563.      * @access  public
  564.      * @param   string  type
  565.      * @param   string  path
  566.      * @param   string  optional target dir
  567.      * @returns bool    success state
  568.      */
  569.     function addPackageFile($type, $path, $dir = "")
  570.     {
  571.         $targetpath = basename($path);
  572.         if ($dir) {
  573.             if ($dir{0} == "/") {
  574.                 return PEAR::raiseError("only relative pathes are allowed as target dir");
  575.             }
  576.             $targetpath = $dir."/".$targetpath;
  577.         }
  578.  
  579.         if (isset($this->packageFiles[$type][$targetpath])) {
  580.             return PEAR::raiseError("duplicate distribution file name '$targetpath'");
  581.         }
  582.  
  583.         $this->packageFiles[$type][$targetpath] = $path;
  584.         return true;
  585.     }
  586.  
  587.     /**
  588.      * Add a source file to be copied to the extension dir
  589.      *
  590.      * @access public
  591.      * @param  string path
  592.      * @param  string optional target dir
  593.      */
  594.     function addSourceFile($name, $dir="") 
  595.     {
  596.         // TODO catch errors returned from addPackageFile
  597.  
  598.         $filename = realpath($name);
  599.  
  600.         if (!is_file($filename)) {
  601.           return PEAR::raiseError("'$name' is not a valid file");
  602.         }
  603.         
  604.         if (!is_readable($filename)) {
  605.           return PEAR::raiseError("'$name' is not readable");
  606.         }
  607.         
  608.         $pathinfo = pathinfo($filename);
  609.         $ext = $pathinfo["extension"];
  610.  
  611.         switch ($ext) {
  612.         case 'c':
  613.           $this->addConfigFragment("AC_PROG_CC");
  614.           $this->addPackageFile('code', $filename);
  615.           break;
  616.         case 'cpp':
  617.         case 'cxx':
  618.         case 'c++':
  619.           $this->addConfigFragment("AC_PROG_CXX");
  620.           $this->addConfigFragment("AC_LANG([C++])");
  621.           $this->addPackageFile('code', $filename);
  622.           break;
  623.         case 'l':
  624.         case 'flex':
  625.           $this->addConfigFragment("AM_PROG_LEX");
  626.           $this->addPackageFile('code', $filename);
  627.           break;
  628.         case 'y':
  629.         case 'bison':
  630.           $this->addConfigFragment("AM_PROG_YACC");
  631.           $this->addPackageFile('code', $filename);
  632.           break;
  633.         default:
  634.           break;
  635.         }
  636.         
  637.         return $this->addPackageFile('copy', $filename, $dir);
  638.     }
  639.  
  640.     /**
  641.      * Add makefile fragment
  642.      *
  643.      * @access public
  644.      * @param  string
  645.      */
  646.     function addMakeFragment($text)
  647.     {
  648.         $this->makefragments[] = $text;
  649.         return true;
  650.     }
  651.             
  652.  
  653.     /**
  654.      * Add config.m4 fragment
  655.      *
  656.      * @access public
  657.      * @param  string
  658.      */
  659.     function addConfigFragment($text, $position="top")
  660.     {
  661.         if (!in_array($position, array("top", "bottom"))) {
  662.             return PEAR::raiseError("'$position' is not a valid config snippet position");
  663.         }
  664.         $this->configfragments[$position][] = $text;
  665.         return true;
  666.     }
  667.  
  668.  
  669.     /**
  670.      * Add acinclude.m4 fragment
  671.      *
  672.      * @access public
  673.      * @param  string
  674.      */
  675.     function addAcIncludeFragment($text, $position="top")
  676.     {
  677.         if (!in_array($position, array("top", "bottom"))) {
  678.             return PEAR::raiseError("'$position' is not a valid config snippet position");
  679.         }
  680.         $this->acfragments[$position][] = $text;
  681.         return true;
  682.     }
  683.             
  684.  
  685.     /**
  686.     * Write .cvsignore entries
  687.     *
  688.     * @access public
  689.     * @param  string  directory to write to
  690.     */
  691.     function writeDotCvsignore()
  692.     {
  693.         $file = new CodeGen_Tools_Outbuf($this->dirpath."/.cvsignore");
  694.  
  695.         // unix specific entries
  696.         if ($this->platform->test("unix")) {
  697.             echo 
  698. "*.lo
  699. *.la
  700. .deps
  701. .libs
  702. Makefile
  703. Makefile.fragments
  704. Makefile.global
  705. Makefile.objects
  706. acinclude.m4
  707. aclocal.m4
  708. autom4te.cache
  709. build
  710. config.cache
  711. config.guess
  712. config.h
  713. config.h.in
  714. config.log
  715. config.nice
  716. config.status
  717. config.sub
  718. configure
  719. configure.in
  720. conftest
  721. conftest.c
  722. include
  723. install-sh
  724. libtool
  725. ltmain.sh
  726. missing
  727. mkinstalldirs
  728. modules
  729. scan_makefile_in.awk
  730. ";
  731.         }
  732.  
  733.         // windows specific entries
  734.         if ($this->platform->test("windows")) {
  735.             echo 
  736. "*.dsw
  737. *.plg
  738. *.opt
  739. *.ncb
  740. Release
  741. Release_inline
  742. Debug
  743. Release_TS
  744. Release_TSDbg
  745. Release_TS_inline
  746. Debug_TS
  747. ";
  748.         }
  749.  
  750.         // "pear package" creates .tgz
  751.         echo "{$this->name}*.tgz\n";
  752.  
  753.         return $file->write();
  754.     }
  755.  
  756.     /**
  757.      * Generate Editor settings block for C source files
  758.      *
  759.      * @access public
  760.      * @return string Editor settings comment block
  761.     */
  762.     function cCodeEditorSettings() 
  763.     {
  764.             return '
  765. /*
  766.  * Local variables:
  767.  * tab-width: 4
  768.  * c-basic-offset: 4
  769.  * End:
  770.  * vim600: noet sw=4 ts=4 fdm=marker
  771.  * vim<600: noet sw=4 ts=4
  772.  */
  773. ';
  774.      }
  775.  
  776.     /**
  777.      * Generate Editor settings block for documentation files
  778.      *
  779.      * @access public
  780.      * @param  int    Directory nesting depth of target file (default: 3)
  781.      * @return string Editor settings comment block
  782.     */
  783.     static function docEditorSettings($level=3) 
  784.     {
  785.         return "";
  786.     }
  787. }
  788.  
  789.  
  790.  
  791. ?>
  792.